From: Lionel Landwerlin Date: Wed, 10 Jul 2013 09:22:07 +0000 (+0100) Subject: st-theme-node: let paint states take weak ref on theme nodes X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~1013^2^2~3960 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=a18fb27d0f41b4c7b8731426d3528dd6bea4bd42;p=gnome-shell.git st-theme-node: let paint states take weak ref on theme nodes When the St theme is changed, the StThemeContext unrefs all the theme nodes cached in it's internal hash table, then emits a signal to notify all theme nodes that the current theme has changed. The problem is that the first StWidget to catch a theme changed signal will trigger a "style-changed" signal catched by its children first. So the theme changed signal can't be processed properly to cleanup StThemeNodePaintState before recomputing the theme. This patch adds a weak ref to the StThemeNode in the StThemeNodePaintState to ensure paint states are properly cleaned up when the associated StThemeNode is freed. https://bugzilla.gnome.org/show_bug.cgi?id=703859 --- diff --git a/src/st/st-theme-node-drawing.c b/src/st/st-theme-node-drawing.c index 0b76f6b2d..e8ba869d3 100644 --- a/src/st/st-theme-node-drawing.c +++ b/src/st/st-theme-node-drawing.c @@ -1391,7 +1391,7 @@ st_theme_node_render_resources (StThemeNodePaintState *state, */ st_theme_node_paint_state_free (state); - state->node = node; + st_theme_node_paint_state_set_node (state, node); state->alloc_width = width; state->alloc_height = height; @@ -1526,7 +1526,7 @@ st_theme_node_update_resources (StThemeNodePaintState *state, } } - state->node = node; + st_theme_node_paint_state_set_node (state, node); state->alloc_width = width; state->alloc_height = height; @@ -2523,8 +2523,9 @@ st_theme_node_paint (StThemeNode *node, } } -void -st_theme_node_paint_state_free (StThemeNodePaintState *state) +static void +st_theme_node_paint_state_node_free_internal (StThemeNodePaintState *state, + gboolean unref_node) { int corner_id; @@ -2539,9 +2540,39 @@ st_theme_node_paint_state_free (StThemeNodePaintState *state) if (state->corner_material[corner_id] != COGL_INVALID_HANDLE) cogl_handle_unref (state->corner_material[corner_id]); + if (unref_node) + st_theme_node_paint_state_set_node (state, NULL); + st_theme_node_paint_state_init (state); } +static void +st_theme_node_paint_state_node_freed (StThemeNodePaintState *state) +{ + st_theme_node_paint_state_node_free_internal (state, FALSE); +} + +void +st_theme_node_paint_state_set_node (StThemeNodePaintState *state, StThemeNode *node) +{ + if (state->node) + g_object_weak_unref (G_OBJECT (state->node), + (GWeakNotify) st_theme_node_paint_state_node_freed, + state); + + state->node = node; + if (state->node) + g_object_weak_ref (G_OBJECT (state->node), + (GWeakNotify) st_theme_node_paint_state_node_freed, + state); +} + +void +st_theme_node_paint_state_free (StThemeNodePaintState *state) +{ + st_theme_node_paint_state_node_free_internal (state, TRUE); +} + void st_theme_node_paint_state_init (StThemeNodePaintState *state) { @@ -2567,7 +2598,7 @@ st_theme_node_paint_state_copy (StThemeNodePaintState *state, st_theme_node_paint_state_free (state); - state->node = other->node; + st_theme_node_paint_state_set_node (state, other->node); state->alloc_width = other->alloc_width; state->alloc_height = other->alloc_height; diff --git a/src/st/st-theme-node.h b/src/st/st-theme-node.h index 8f3a37810..5fffa6343 100644 --- a/src/st/st-theme-node.h +++ b/src/st/st-theme-node.h @@ -281,6 +281,8 @@ void st_theme_node_paint_state_free (StThemeNodePaintState *state); void st_theme_node_paint_state_copy (StThemeNodePaintState *state, StThemeNodePaintState *other); void st_theme_node_paint_state_invalidate (StThemeNodePaintState *state); +void st_theme_node_paint_state_set_node (StThemeNodePaintState *state, + StThemeNode *node); G_END_DECLS